package org.bes.WinClass;

import org.bes.api.IVersionController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.json.*;
import javax.json.stream.JsonGenerator;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.stream.Collectors;


import static org.bes.WinClass.FileManager.*;
import static org.bes.WinClass.Rollbacker.versionData;
import static org.bes.WinClass.UpdatePatch.jarFileInfoList;

import static org.bes.utils.StrPathUtils.getRelavtivePath;

public class VersionControl implements IVersionController {

    public static Path versionFilePath = FileManager.getPatchParentDir().resolve(VERSION_FILE);

    public static Map<String, List<File>> versionFileMap = new TreeMap<>();
    static Map<String, String> fileVersions = new HashMap<>();   // 普通文件版本

    private static final JsonArrayBuilder jarFilesArray = Json.createArrayBuilder();
    private static final Logger log = LoggerFactory.getLogger(VersionControl.class);

    public VersionControl() {


    }

    // 统一记录所有操作
    public static void logOperations(List<FileOperation> fileOperations) {

        Map<String, JsonObjectBuilder> commonFileMap = new HashMap<>(); // 用来保存每个文件的 JsonObjectBuilder
        Map<String, JsonObjectBuilder> jarFileMap = new HashMap<>();

        JsonObjectBuilder allJsonObjectBuilder = Json.createObjectBuilder();

        //JsonArrayBuilder jarFileArrayBuilder = Json.createArrayBuilder();

        // 读取现有的 JSON 文件（如果存在）
        JsonObject existingJson = null;
        if (Files.exists(versionFilePath)) {  // 检查文件是否存在
            try (InputStream inputStream = Files.newInputStream(versionFilePath);
                 JsonReader reader = Json.createReader(inputStream)) {
                existingJson = reader.readObject();
            } catch (IOException e) {
                log.error("Error reading existing JSON file: " + e.getMessage());
            }
        }

        // 如果现有 JSON 文件存在，加载其中的文件数据
        if (existingJson != null) {
            JsonArray existingCommonFiles = existingJson.getJsonArray("common_files");
            JsonArray existingJarFiles = existingJson.getJsonArray("jar_files");

            // 处理现有的 "common_files"
            for (JsonObject commonFile : existingCommonFiles.getValuesAs(JsonObject.class)) {
                String filePath = commonFile.getString("common_file");
                commonFileMap.put(filePath, Json.createObjectBuilder(commonFile));  // 更新 map
            }

            // 处理现有的 "jar_files"
            for (JsonObject jarFile : existingJarFiles.getValuesAs(JsonObject.class)) {
                String filePath = jarFile.getString("jar_file");
                jarFileMap.put(filePath, Json.createObjectBuilder(jarFile));  // 更新 map
            }
        }



        for(FileOperation fileOperation : fileOperations){
            // is jar file
            if (!fileOperation.jarFileOperations.isEmpty()) {
                if (jarFileMap.containsKey(fileOperation.filePath.toString())){
                    // 如果 jar_file 已存在，获取已存在的 JsonObjectBuilder
                    JsonObjectBuilder currentJsonObjectBuilder = jarFileMap.get(fileOperation.filePath.toString());
                    System.out.println(fileOperation.filePath);
                    JsonObject currentJsonObject = currentJsonObjectBuilder.build();

                    currentJsonObjectBuilder.add("jar_file", fileOperation.filePath.toString());

                    String currentVersion = currentJsonObject.getString("latest_operation_version");
                    if (compareVersion(currentVersion, fileOperation.version) < 0) {
                        // 更新 latest_version
                        currentJsonObjectBuilder.add("latest_operation_version", fileOperation.version);
                    }else {
                        currentJsonObjectBuilder.add("latest_operation_version", currentVersion);
                    }

                    currentJsonObjectBuilder.add("files", currentJsonObject.getJsonArray("files"));
                    //合并files
                    JsonArray currentFilesArray = currentJsonObject.getJsonArray("files");

                    JsonArrayBuilder updatedFilesArrayBuilder = MergeFile(currentFilesArray, fileOperation.jarFileOperations);

                    // 更新 jsonObjectBuilder 中的 files
                    currentJsonObjectBuilder.add("files", updatedFilesArrayBuilder);

                } else {
                    JsonObjectBuilder jsonObjectBuilder = Json.createObjectBuilder();
                    jsonObjectBuilder.add("jar_file", fileOperation.filePath.toString())
                            .add("latest_operation_version", fileOperation.version);

                    JsonArrayBuilder filesArrayBuilder = Json.createArrayBuilder();
                    for (JarFileOperation jarFileOperation : fileOperation.jarFileOperations) {
                        JsonObjectBuilder fileObjectBuilder = Json.createObjectBuilder();
                        fileObjectBuilder.add("file", jarFileOperation.filePath)
                                .add("latest_version", jarFileOperation.version);

                        JsonArrayBuilder operationsArrayBuilder = Json.createArrayBuilder();
                        operationsArrayBuilder.add(Json.createObjectBuilder()
                                .add("type", jarFileOperation.operation)
                                .add("version", jarFileOperation.version));

                        fileObjectBuilder.add("operations", operationsArrayBuilder);

                        filesArrayBuilder.add(fileObjectBuilder);
                    }

                    jsonObjectBuilder.add("files", filesArrayBuilder);

                    jarFileMap.put(fileOperation.filePath.toString(), jsonObjectBuilder);
                }

            } else {  // 处理 common file
                if (commonFileMap.containsKey(fileOperation.filePath.toString())) {
                    // 如果文件路径已经存在，更新 latest_version 和合并 operations
                    JsonObjectBuilder commonFileObjectBuilder = commonFileMap.get(fileOperation.filePath.toString());

                    JsonObject commonFileJson = commonFileObjectBuilder.build();
                    commonFileObjectBuilder.add("common_file", fileOperation.filePath.toString());

                    String currentVersion = commonFileJson.getString("latest_version");

                    // 只更新 latest_version 如果文件版本更高
                    if (compareVersion(currentVersion, fileOperation.version) < 0) {
                        // 更新 latest_version
                        commonFileObjectBuilder.add("latest_version", fileOperation.version);
                    } else {
                        commonFileObjectBuilder.add("latest_version", currentVersion);
                    }

                    // 合并 operations
                    JsonArrayBuilder operationsArrayBuilder = Json.createArrayBuilder();
                    JsonArray operations = commonFileJson.getJsonArray("operations");
                    operations.forEach(op -> operationsArrayBuilder.add(op));

                    operationsArrayBuilder.add(Json.createObjectBuilder()
                            .add("type", fileOperation.operation)
                            .add("version", fileOperation.version));


                    commonFileObjectBuilder.add("operations", operationsArrayBuilder);



                } else {
                    // 如果文件路径不存在，创建新的 JsonObjectBuilder
                    JsonObjectBuilder commonFileObjectBuilder = Json.createObjectBuilder();
                    commonFileObjectBuilder.add("common_file", fileOperation.filePath.toString());
                    commonFileObjectBuilder.add("latest_version", fileOperation.version);

                    JsonArrayBuilder operationsArrayBuilder = Json.createArrayBuilder();
                    operationsArrayBuilder.add(Json.createObjectBuilder()
                            .add("type", fileOperation.operation)
                            .add("version", fileOperation.version));
                    commonFileObjectBuilder.add("operations", operationsArrayBuilder);

                    // 保存到 map 中
                    commonFileMap.put(fileOperation.filePath.toString(), commonFileObjectBuilder);
                }
            }
        }

        // 合并所有 common files
        JsonArrayBuilder commonFileArrayBuilder = Json.createArrayBuilder();
        for (JsonObjectBuilder builder : commonFileMap.values()) {
            commonFileArrayBuilder.add(builder);
        }
        // 合并所有 common files
        JsonArrayBuilder jarFileArrayBuilder = Json.createArrayBuilder();
        for (JsonObjectBuilder builder : jarFileMap.values()) {
            jarFileArrayBuilder.add(builder);
        }


        // 将 common files 和 jar files 加入最终的 JSON
        allJsonObjectBuilder.add("common_files", commonFileArrayBuilder);
        allJsonObjectBuilder.add("jar_files", jarFileArrayBuilder);

        // 生成最终 JSON
        JsonObject finalJson = allJsonObjectBuilder.build();
        try (FileWriter writer = new FileWriter(getPatchParentDir().resolve(VERSION_FILE).toFile())) {
            JsonWriter jsonWriter = Json.createWriterFactory(
                    new java.util.HashMap<String, Boolean>() {{
                        put(JsonGenerator.PRETTY_PRINTING, true);
                    }}).createWriter(writer);
            jsonWriter.write(finalJson);
        } catch (IOException e) {
            log.error(e.getMessage());
        }
    }

    public static JsonArrayBuilder MergeFile(JsonArray currentFilesArray, List<JarFileOperation> jarFileOperations) {
        JsonArrayBuilder updatedFilesArrayBuilder = Json.createArrayBuilder();
        // 合并现有文件和新的文件操作
        for (JarFileOperation jarFileOperation : jarFileOperations) {
            boolean found = false;
            // 查找是否已有相同的文件
            for (JsonObject currentFile : currentFilesArray.getValuesAs(JsonObject.class)) {
                String currentFileName = currentFile.getString("file");
                if (currentFileName.equals(jarFileOperation.filePath)) {
                    // 找到同名文件，合并 operations
                    JsonArrayBuilder operationsArrayBuilder = Json.createArrayBuilder();

                    // 添加当前文件已有的操作
                    JsonArray currentOperationsArray = currentFile.getJsonArray("operations");
                    for (JsonObject operation : currentOperationsArray.getValuesAs(JsonObject.class)) {
                        operationsArrayBuilder.add(operation);
                    }

                    // 添加新的操作
                    operationsArrayBuilder.add(Json.createObjectBuilder()
                            .add("type", jarFileOperation.operation)
                            .add("version", jarFileOperation.version));

                    // 更新文件对象中的 operations 和 latest_version
                    JsonObjectBuilder updatedFileObjectBuilder = Json.createObjectBuilder(currentFile);
                    updatedFileObjectBuilder.add("operations", operationsArrayBuilder);

                    // 根据 operations 中的最大版本来更新 latest_version
                    String latestVersionInOperations = jarFileOperation.version;
                    for (JsonObject operation : operationsArrayBuilder.build().getValuesAs(JsonObject.class)) {
                        String operationVersion = operation.getString("version");
                        if (compareVersion(operationVersion, latestVersionInOperations) > 0) {
                            latestVersionInOperations = operationVersion;
                        }
                    }
                    updatedFileObjectBuilder.add("latest_version", latestVersionInOperations);

                    updatedFilesArrayBuilder.add(updatedFileObjectBuilder);
                    found = true;
                    break;
                }
            }

            // 如果没有找到同名文件，则直接添加新文件
            if (!found) {
                JsonObjectBuilder newFileObjectBuilder = Json.createObjectBuilder();
                newFileObjectBuilder.add("file", jarFileOperation.filePath)
                        .add("latest_version", jarFileOperation.version);

                JsonArrayBuilder newOperationsArrayBuilder = Json.createArrayBuilder();
                newOperationsArrayBuilder.add(Json.createObjectBuilder()
                        .add("type", jarFileOperation.operation)
                        .add("version", jarFileOperation.version));

                newFileObjectBuilder.add("operations", newOperationsArrayBuilder);

                updatedFilesArrayBuilder.add(newFileObjectBuilder);
            }
        }

        // 合并现有文件数组和更新后的文件数组
        currentFilesArray.forEach(file -> updatedFilesArrayBuilder.add(file));

        return updatedFilesArrayBuilder;
    }




    public static int compareVersion(String version1, String version2) {
        String[] v1Parts = version1.split("\\.");
        String[] v2Parts = version2.split("\\.");

        for (int i = 0; i < Math.min(v1Parts.length, v2Parts.length); i++) {
            int result = Integer.compare(Integer.parseInt(v1Parts[i]), Integer.parseInt(v2Parts[i]));
            if (result != 0) {
                return result;
            }
        }
        return Integer.compare(v1Parts.length, v2Parts.length);
    }








    //public void updateVersion() throws IOException {
    //    // 获取 version 信息
    //    String newVersion = FileManager.version;
    //    Path versionFilePath = FileManager.getPatchParentDir().resolve(FileManager.VERSION_FILE);
    //    File versionFile = new File(String.valueOf(versionFilePath));
    //
    //    // 如果 .version 文件存在，开始更新
    //    if (versionFile.exists() && versionFile.isFile()) {
    //        List<String> versionLines = Files.readAllLines(versionFile.toPath(), StandardCharsets.UTF_8);
    //
    //        // 遍历 FileManager.fileList 中的所有文件
    //        for (File file : allFilesToUpdate) {
    //            // 获取文件的相对路径
    //            Path filePath = FileManager.getBackupDir().relativize(file.toPath());
    //            String relativePath = filePath.toString();
    //
    //            boolean versionUpdated = false;
    //
    //            // 遍历 .version 文件的所有行，查找是否有匹配的路径
    //            for (int i = 0; i < versionLines.size(); i++) {
    //                String line = versionLines.get(i);
    //                if (line.startsWith(relativePath)) {
    //                    // 如果匹配的路径存在，更新版本号
    //                    String[] parts = line.split("=");
    //                    if (parts.length == 2) {
    //                        // 更新为新的版本号
    //                        versionLines.set(i, relativePath + "=" + newVersion);
    //                        versionUpdated = true;
    //                    }
    //                }
    //            }
    //
    //            // 如果版本信息被更新，则写回文件
    //            if (versionUpdated) {
    //                Files.write(versionFile.toPath(), versionLines, StandardCharsets.UTF_8);
    //                log.info("已更新文件的版本: " + relativePath);
    //            }
    //        }
    //    } else {
    //        log.warn(".version 文件不存在，无法更新版本信息.");
    //    }
    //}


    // 更新 JSON 文件中的 JAR 部分
    public static void updateJarVersionInJson(Path jsonFilePath, List<JarFileInfo> jarFileInfoList) throws IOException {
        // 读取现有的 JSON 文件
        JsonReader jsonReader = Json.createReader(new FileReader(jsonFilePath.toFile()));
        JsonObject rootObject = jsonReader.readObject();
        jsonReader.close();

        // 获取现有的 jar_files 数组
        JsonArrayBuilder jarFilesArrayBuilder = Json.createArrayBuilder();
        JsonArray jarFilesArray = rootObject.getJsonArray("jar_files");

        // 遍历 JAR 文件信息列表，更新 JSON 中的对应部分
        for (JarFileInfo jarFileInfo : jarFileInfoList) {
            JsonObjectBuilder jarFileObject = Json.createObjectBuilder();
            jarFileObject.add("jar_file", jarFileInfo.jarFilePath.toString());
            jarFileObject.add("max_version", jarFileInfo.maxVersion);

            // 处理 JAR 文件的内容（content_files）
            JsonObjectBuilder contentFilesBuilder = Json.createObjectBuilder();
            for (Map.Entry<String, String> entry : jarFileInfo.contentFiles.entrySet()) {
                contentFilesBuilder.add(entry.getKey(), entry.getValue());
            }
            jarFileObject.add("content_files", contentFilesBuilder);

            // 添加更新后的 JAR 文件信息
            jarFilesArrayBuilder.add(jarFileObject);
        }

        // 获取 file_versions
        JsonObjectBuilder fileVersionsBuilder = Json.createObjectBuilder();
        JsonObject fileVersions = rootObject.getJsonObject("file_versions");
        for (String key : fileVersions.keySet()) {
            fileVersionsBuilder.add(key, fileVersions.getString(key));
        }

        // 创建新的 JSON 对象并更新
        JsonObject updatedJson = Json.createObjectBuilder()
                .add("file_versions", fileVersionsBuilder)
                .add("jar_files", jarFilesArrayBuilder)
                .build();

        // 将更新后的 JSON 写回文件
        try (JsonWriter jsonWriter = Json.createWriter(new FileWriter(jsonFilePath.toFile()))) {
            jsonWriter.writeObject(updatedJson);
        }

        System.out.println("JSON file updated successfully!");
    }

}
